using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Globalization;
using System.Diagnostics;
using Lizk.WebScraper;
using HtmlAgilityPack;

namespace AnimeScrapers
{
    public class AnimeDBScraper : Scraper
    {
        #region Scraper Members
        Regex r = new Regex(".*?animedb.pl\\?show=anime&amp;aid=(\\d+)\">(?:<i>)?(.+?)(?:</i>)?</a>.*?"), yearR = new Regex(@"(\d{4})"), runtime = new Regex(@"(\d+)m");

        public override ScraperResult[] Search(string search)
        {
            List<ScraperResult> titles = new List<ScraperResult>();
            UpdateProgress(new ScraperEventArgs("Connecting to anidb.info", ScraperEventArgs.ScaperStatus.Connecting));

            HttpWebRequest webRequest = (HttpWebRequest)(WebRequest.Create("http://anidb.net/perl-bin/animedb.pl?show=animelist&adb.search=" + HttpUtility.HtmlEncode(search) + "&do.search=search"));
            webRequest.AutomaticDecompression = DecompressionMethods.GZip;
            webRequest.AllowAutoRedirect = true;
            WebResponse response = webRequest.GetResponse();
            
            if (response.ResponseUri.AbsoluteUri.Contains("aid="))
            {
                Regex reg = new Regex(@"aid=(\d+)");
                Match m = reg.Match(response.ResponseUri.AbsoluteUri);
                UpdateProgress(new ScraperEventArgs("Search completed", ScraperEventArgs.ScaperStatus.Done));
                if (m.Success)
                {
                    string input;
                    using (StreamReader s = new StreamReader(response.GetResponseStream()))
                    {
                        UpdateProgress(new ScraperEventArgs("Waiting for anidb.info", ScraperEventArgs.ScaperStatus.Downloading));
                        input = s.ReadToEnd();
                    }
                    ScraperResult ar = new ScraperResult(m.Groups[1].ToString());
                    FillTitleInfo(input, ar);
                    UpdateProgress(new ScraperEventArgs("Information Scraped", ScraperEventArgs.ScaperStatus.Done)); 
                    ScrapeComplete(ar);
                    return new ScraperResult[] { ar };
                
                
                
                }
                else
                    return new ScraperResult[0];
            }
            
            using (StreamReader s = new StreamReader(response.GetResponseStream()))
            {
                UpdateProgress(new ScraperEventArgs("Waiting for anidb.info", ScraperEventArgs.ScaperStatus.Downloading));
                string line, all ="";
                while ((line = s.ReadLine()) != null)
                {
                    all += line;
                    Match m = r.Match(line);
                    if (m.Success)
                    {
                        ScraperResult ar = new ScraperResult(m.Groups[1].ToString());
                        ar.Title = HttpUtility.HtmlDecode(m.Groups[2].ToString());
                        
                        line = s.ReadLine();
//                        ar.Type = HttpUtility.HtmlDecode(Scrape(0, line, "> ", " <"));
                        line = s.ReadLine();
                        string eps = Scrape(0, line, "> ", " <");
//                        if (Regex.IsMatch(eps, @"^\d+$"))
//                            ar.Parts = Int32.Parse(eps);
                        line = s.ReadLine();
                        
                        string year = Scrape(0, line, "> ", " <");
                        m = yearR.Match(year);
                        if (m.Success)
                        {
                            ar.Year = Int32.Parse(m.Groups[1].ToString());
                        }
                        
                        titles.Add(ar);
                    }
                }
            }
            UpdateProgress(new ScraperEventArgs("Search completed", ScraperEventArgs.ScaperStatus.Done));
            SearchComplete(titles);
            return titles.ToArray();       
        }
        
        private void FillTitleInfo(string input, ScraperResult ar)
        {
            HtmlDocument html = new HtmlDocument();
            html.LoadHtml(input);


            ar.Title = Regex.Replace(html.DocumentNode.SelectSingleNode("//div[@class='data']//tr[th='Main Title']/td").InnerText.Trim(), @"\(.*?\)$", "").Trim();

            string y = html.DocumentNode.SelectSingleNode("//div[@class='data']//tr[th='Year']/td").InnerText.Trim();

            Match match = Regex.Match(y, @"^\d{2}\.\d{2}\.(\d{4})");
            if (match.Success)
                ar.Year = Int32.Parse(match.Groups[1].Value);

            string desc = html.DocumentNode.SelectSingleNode("//div[@class='desc']").InnerText.Trim();
            ar.Summary = desc;
            foreach (var node in html.DocumentNode.SelectNodes("//table[@id='eplist']//td[@class='id eid']"))
            {
                int ep;

                if (!Int32.TryParse(node.FirstChild.InnerText, out ep))
                    continue;

                HtmlNode titleNode = node.NextSibling;
                while (titleNode != null && titleNode.NodeType != HtmlNodeType.Element)
                    titleNode = titleNode.NextSibling;

                if (titleNode == null)
                    continue;
                    string epName = Regex.Replace(titleNode.InnerText.Trim(), @"\(.*?\)$", "").Trim();
                Episode newEpisode = new Episode(epName);
                newEpisode.Season = 0;
                newEpisode .EpisodeNumber = ep;
                ar.Episodes.Add(newEpisode);
            }

            ar.ImageUrl = html.DocumentNode.SelectSingleNode("//div[@class='image']/img").GetAttributeValue("src", "");



            return;



        }


        public override ScraperResult GetTitleInfo(string id)
        {
            UpdateProgress(new ScraperEventArgs("Connecting to anidb.info", ScraperEventArgs.ScaperStatus.Connecting));
            HttpWebRequest webRequest = (HttpWebRequest)(WebRequest.Create("http://anidb.info/perl-bin/animedb.pl?show=anime&aid=" + HttpUtility.HtmlEncode(id) + "&expandall=1"));
            webRequest.AutomaticDecompression = DecompressionMethods.GZip;

            WebResponse response = webRequest.GetResponse();
            ScraperResult ar = new ScraperResult(id);
            string input;
            using (StreamReader s = new StreamReader(response.GetResponseStream()))
            {
                input = s.ReadToEnd();
            }
            FillTitleInfo(input, ar);
            UpdateProgress(new ScraperEventArgs("Information Scraped", ScraperEventArgs.ScaperStatus.Done));
            ScrapeComplete(ar); 
            return ar;
        }

        #endregion
    }

  
}
